using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Utilities;




namespace Services.Menu
{
    public class LoadingComponent : DrawableGameComponent
    {
        SpriteBatch spritebatch;
        Texture2D pixel;
        Color color;
        Color bgcolor;
        ArrayList<Rectangle> elements;
        int num_elements;
        int element_size = 8;
        int element_distance = 40;
        float fast_moltiplier = 2;
        float slow_moltiplier = 1;
        DisplayOrientation prev_orientation;
        int width = 480;
        int height = 800;
        Action abortLoading;
        #region Constructors
        public LoadingComponent(Game game, Color color, Color bgcolor, int num_elements, Action abortLoading)
            : base(game)
        {
            this.color = color;
            this.bgcolor = bgcolor;
            this.num_elements = num_elements;
            if (num_elements % 2 == 0)
                num_elements++;
            this.abortLoading = abortLoading;
        }
        public LoadingComponent(Game game, Color color, Color bgcolor, int num_elements)
            : this(game, color, bgcolor, num_elements, null)
        {
        }
        public LoadingComponent(Game game, Color color, Color bgcolor, Action abortLoading)
            : this(game, color, bgcolor, 5, abortLoading)
        { }
        public LoadingComponent(Game game, Color color, Color bgcolor)
            : this(game, color, bgcolor, 5, null)
        {
        }
        #endregion

        public void SetAbortAction(Action abortAction)
        {
            abortLoading = abortAction;
        }
        public override void Initialize()
        {
            spritebatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            //screen_transform = Game.ScreenTransformMatrix(graphics);
            pixel = Game.Content.Load<Texture2D>("Menu\\WhitePixel");
            elements = new ArrayList<Rectangle>();
            base.Initialize();
            ResetElements();
        }

        
        void ResetElements()
        {
            elements.Clear();
            int y=0;
            if (GraphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait)
                y = 400 - element_size / 2;
            else
                y = 240 - element_size / 2;
            for (int i = 0; i < num_elements; i++)
            {
                elements.Add(new Rectangle(0 - element_size - i * (element_size + element_distance), y, element_size, element_size));
            }
            if (GraphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait)
            {
                width = 480;
                height = 800;
                fast_moltiplier = 2;
                slow_moltiplier = 1;
                element_distance = 40;
            }
            else
            {
                width = 800;
                height = 480;
                fast_moltiplier = 4;
                slow_moltiplier = 2;
                element_distance = 100;
            }
        }

        
        public override void Update(GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
            if(prev_orientation != GraphicsDevice.PresentationParameters.DisplayOrientation)
            {    
                prev_orientation = GraphicsDevice.PresentationParameters.DisplayOrientation;
                ResetElements();
                for (int i = 0; i < Game.Components.Count; i++)
                {
                    var c = Game.Components[i];
                    try
                    {
                        if (prev_orientation == DisplayOrientation.Portrait)
                            ((OrientableScreen)c).SetPortraitOrientation();
                        else
                            ((OrientableScreen)c).SetLandScapeOrientation();
                    }
                    catch (Exception e)
                    {
                        e.ToString();
                    }
                        
                }
            }

            for (int i = 0; i < elements.Count; i++)
            {
                if (elements[i].X < width)
                    break;
                if (i == elements.Count - 1)
                    ResetElements();
            }
            for (int i = 0; i < elements.Count; i++)
            {
                var r = elements[i];
                if (r.X < width / 3 || r.X > width * 2 / 3)
                    r.X += (int)(100*dt * fast_moltiplier);
                else if(r.X >= width / 3 && r.X <= width * 2 / 3)
                    r.X += (int)(100 * dt * slow_moltiplier);
                elements[i] = r;
            }
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                Game.Components.Remove(this);
                if (abortLoading != null)
                    abortLoading();
                return;
            } 
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //GraphicsDevice.Clear(bgcolor);

            
            spritebatch.Begin();
            spritebatch.Draw(pixel, new Rectangle(0, 0, width, height), bgcolor);
            for (int i = 0; i < elements.Count; i++)
                spritebatch.Draw(pixel, elements[i], color);
            
            spritebatch.End();

            base.Draw(gameTime);
        }
    }
}
